import pygame, sys
from pygame import Rect
import random
#from hexconfig import *
from pygame.draw import *

COLORKEY = (255,255,255)

class Actor():
    # Initialization.
    # Arguments:
    #     pygame.Surface sprite - the actor's icon.
    #     tuple (x, y) location - (optional) the actor's starting location in the world.
    def __init__(self, spriteSheet, size, game, location = (0, 0)):
        self.game = game
        self.imgSheet = spriteSheet
        #self.imgSheet.set_colorkey(COLORKEY)
        #self.imgSheet = self.imgSheet.convert()

        self.imgSize = size
        self.imgState =  3
        self.imgFrame = 0
        self.img = pygame.Surface(self.imgSize)
        self.img.set_colorkey(COLORKEY)
        self.img = self.img.convert()

        self.img.blit(self.imgSheet,(0,0),(self.imgFrame*self.imgSize[0],\
                    self.imgState*self.imgSize[1],self.imgSize[0],self.imgSize[1]))

        self.drawRect = self.img.get_rect()
        self.drawDisp = [[0,0]]#[((self.imgSize[0]*2)-self.imgSize[0]*2)/2, (self.imgSize[1]*2)-self.imgSize[1]*2]

        self.vel = [0.0,0.0]

        self.colRect = pygame.Rect((location[0] - 1, location[1] - 1),(self.imgSize[0]+2,self.imgSize[1]+2))
        self.colliding = [False,False,False,False]# instead of self.collidingUp, use self.colliding[UP]

        self.keyMap={"left":False, "right":False, "jump":False,"crouch":False}

        self.debugVects = []
        self.facingLeft = True
        self.isPlayer = False
        #self.motionConfig = DEFAULTMOTIONCONFIG

    def update(self,etime):
        self.updateMovement(etime)
        self.updateCollisions()

    def updateMovement(self,etime):
        #takes care of general motion math
        print "IN THE GENERAL UPDATEMOVEMENT!  OHNO!"
        return

    # Test for and handle collisions.
    def updateCollisions(self):
        # Repeatedly test for and shift collisions until all collisions are within tolerance
        needsResolution = True

        colRectShiftFlag = [False,False]

        while needsResolution:
            self.colliding[UP] = False
            self.colliding[DOWN] = False
            self.colliding[LEFT] = False
            self.colliding[RIGHT] = False


            # level collisions
            colliders = self.game.world.getCollidersForRect(self.colRect,self.isPlayer)
            if len(colliders) == 0: needsResolution = False # No collisions
            else: # There are collisions, handle the first one
                needsResolution = False # Might not need update.
                for collisionPair in colliders:
                    collider = collisionPair[0]
                    incursionDepthH = 0
                    incursionDepthV = 0
                    if self.colRect.left < collider.right and self.colRect.right > collider.right:
                        incursionDepthH = self.colRect.left - collider.right
                    elif self.colRect.right > collider.left and self.colRect.left < collider.left:
                        incursionDepthH = self.colRect.right - collider.left
                    if self.colRect.top < collider.bottom and self.colRect.bottom > collider.bottom:
                        incursionDepthV =  self.colRect.top - collider.bottom
                    elif self.colRect.bottom > collider.top and self.colRect.top < collider.top:
                        incursionDepthV = self.colRect.bottom - collider.top

                    # Resolve the incursion of the smallest magnitude
                    if abs(incursionDepthH) == 1 and abs(incursionDepthV) == 1:
                        pass
                    elif abs(incursionDepthH) < abs(incursionDepthV):
                        if abs(incursionDepthH) > 1:
                            needsResolution = True
                            self.colRect.move_ip(-1 * incursionDepthH + incursionDepthH/abs(incursionDepthH), 0)
                            colRectShiftFlag[0] = True
                        elif incursionDepthH == -1:
                            self.colliding[LEFT]= True
                        elif incursionDepthH == 1:
                            self.colliding[RIGHT] = True
                    else:
                        if abs(incursionDepthV) > 1:
                            needsResolution = True
                            self.colRect.move_ip(0, -1 * incursionDepthV + incursionDepthV/abs(incursionDepthV))
                            colRectShiftFlag[1] = True
                        elif incursionDepthV == -1:
                            self.colliding[UP] = True
                        elif incursionDepthV == 1:
                            self.colliding[DOWN] = True
                    if needsResolution: break
        return colRectShiftFlag

    def getPushed(self, v, theta):
        self.vel[0] += dx(v,theta)
        self.vel[1] += dy(v,theta)

    def setKey(self,key,value):
        self.keyMap[key] = value

    def setImgIndex(self,state,frame = -1):
        #print "trying to change from", self.imgState, "to", state
        #if not self.imgState == state:
        self.imgState = state
        if frame == -1:
            frame = 0
        self.imgFrame = frame
        self.img.blit(self.imgSheet,(0,0),((self.imgFrame*self.imgSize[0],self.imgState*self.imgSize[1]),self.imgSize))
            #print "         changed:",self.imgState
        if not self.imgFrame == frame:
            pass

    def draw(self,surface,origin =(0,0),debug = False):
        self.drawRect.topleft = (self.colRect.left + self.drawDisp[self.imgState][0]\
                - origin[0]+1,1+self.colRect.top + self.drawDisp[self.imgState][1]-origin[1])

        self.drawImg(surface,origin)
        if debug:
            self.drawDebugVects(surface)
        self.debugVects = []

    def drawDebugVects(self,surface):
        for v in self.debugVects:
            pt2 = (self.drawRect.center[0]+dx(v[0],v[1]),self.drawRect.center[1]+dy(v[0],v[1]))
            pygame.draw.line(surface,v[2],self.drawRect.center,pt2,3)

    def drawImg(self, surface, origin):

        if not self.rot == 0.0:

            img = pygame.transform.rotate(self.img,self.rot)
            loc = img.get_rect(center = self.colRect.center ).topleft
        else:
            img = self.img
            loc = self.drawRect.topleft
            
        if self.facingLeft == True:
            surface.blit(img, loc)
        else:
            surface.blit(pygame.transform.flip(img, True, False),\
                     loc)


